package com.zj.study.sync;

import java.time.LocalDateTime;
import java.util.function.Consumer;
import java.util.function.Supplier;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 赵赳
 * @since 2021/12/28 10:11
 */
@Slf4j
@RestController
public class SyncTest {

  /**
   * 测试延迟同步方法
   *
   * @return success
   */
  @GetMapping("/test/sync")
  public String testSync() {
    syncPaymentResult();
    return "success";
  }

  /**
   * 将自定义的Consumer方法覆盖同步器的方式去执行响应操作
   */
  public void syncPaymentResult() {

    /* 成功处理方法 */
    Consumer<RefundQueryResult> setSuccess = success -> {
      success.setOrderTime(LocalDateTime.now())
          .setRefundAmount(10000L)
          .setRefundTradeNo("RP14456451531515315");
      log.info("接收到成功消息：{}", success);
    };

    /* 失败处理方法 */
    Consumer<RefundQueryResult> setFail = success -> {
      success.setErrMsg("请求失败");
      log.info("接收到失败消息：{}", success);
    };

    /* 同步执行器 */
    new RefundResultSyncer(this::doRefundQuery)
        .setOnSuccess(setSuccess)
        .setOnFail(setFail)
        .run();
  }

  private RefundQueryResult doRefundQuery() {
    return new RefundQueryResult()
        .setSuccess(true)
        .setRefundNo("RP14456451531")
        .setFinishTime(LocalDateTime.now())
        .setTradeStateEnum(RefundTradeStateEnum.REFUNDED_SUCCESS);
  }

  @Setter
  @Accessors(chain = true)
  private static class RefundResultSyncer {

    // 默认值: 啥也不干
    private static final Consumer<RefundQueryResult> DO_NOTHING = ignored -> {
    };

    /**
     * 请求失败
     */
    @NonNull
    private Consumer<RefundQueryResult> onRequestFail = DO_NOTHING;

    /**
     * 请求成功
     */
    @NonNull
    private Consumer<RefundQueryResult> onRequestSuccess = DO_NOTHING;

    /**
     * 请求失败: 网络异常
     */
    @NonNull
    private Consumer<RefundQueryResult> onNetworkError = DO_NOTHING;

    /**
     * 已受理
     */
    @NonNull
    private Consumer<RefundQueryResult> onAccepted = DO_NOTHING;

    /**
     * 正在处理
     */
    @NonNull
    private Consumer<RefundQueryResult> onProgress = DO_NOTHING;

    /**
     * 退款失败
     */
    @NonNull
    private Consumer<RefundQueryResult> onFail = DO_NOTHING;

    /**
     * 退款成功
     */
    @NonNull
    private Consumer<RefundQueryResult> onSuccess = DO_NOTHING;

    @NonNull
    private final Supplier<RefundQueryResult> supplier;

    public RefundResultSyncer(@NonNull Supplier<RefundQueryResult> supplier) {
      this.supplier = supplier;
    }

    public void run() {
      var result = supplier.get();
      if (!result.isSuccess()) {
        if (result.isNetworkError() && onNetworkError != DO_NOTHING) {
          onNetworkError.accept(result);
        } else {
          onRequestFail.accept(result);
        }
        return;
      }

      onRequestSuccess.accept(result);
      switch (result.getTradeStateEnum()) {
        case ACCEPT:
          onAccepted.accept(result);
          break;
        case PRE_PAYMENT:
          onProgress.accept(result);
          break;
        case FAIL:
          onFail.accept(result);
          break;
        case REFUNDED_SUCCESS:
          onSuccess.accept(result);
          break;
        default:
          throw new IllegalStateException("不支持的退款结果枚举值: " + result.getTradeStateEnum());
      }
    }
  }

}
